package cc.buttfu.thingbento;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.Queue;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.preference.PreferenceManager;
import android.widget.ImageView;

/**
 * @author dislink.now
 * 
 * Class for queueing a list of images to be loaded from a URL
 * into an ImageView one by one, in a separate thread from the
 * main UI class.
 *
 */
public class ImageLoader implements Runnable {

	/**
	 * This class is purely a workaround for android bug 6066 
	 */
	private static class FlushedInputStream extends FilterInputStream {
		public FlushedInputStream(InputStream inputStream) {
			super(inputStream);
		}

		@Override
		public long skip(long n) throws IOException {
			long totalBytesSkipped = 0L;
			while (totalBytesSkipped < n) {
				long bytesSkipped = in.skip(n - totalBytesSkipped);
				if (bytesSkipped == 0L) {
					int aByte = read();
					if (aByte < 0) {
						break; // we reached EOF
					} else {
						bytesSkipped = 1; // we read one byte
					}
				}
				totalBytesSkipped += bytesSkipped;
			}
			return totalBytesSkipped;
		}
	}

	private class ImageLoaderBundle {
		ImageView view;
		String url;
	}

	Queue<ImageLoaderBundle> imageQueue;
	private Context context;

	public ImageLoader(Context context) {
		this.context = context;
		imageQueue = new LinkedList<ImageLoaderBundle>();
	}

	/**
	 * @param url URL of image to be queued for loading
	 * @param view ImageView which will display the image once it is loaded
	 */
	public void queueImage(String url, ImageView view) {
		ImageLoaderBundle b = new ImageLoaderBundle();
		b.url = url;
		b.view = view;
		imageQueue.add(b);
	}

	@Override
	public void run() {

		/* Runs forever until thread is deleted, but remains in a 
		 * wait state until more images are added to the queue.
		 */
		while (true) {

			while (!imageQueue.isEmpty()) {
				final ImageLoaderBundle b = imageQueue.poll();

				/* Load image from URL */
				
				URL myFileUrl = null;
				try {
					myFileUrl = new URL(b.url);
				} catch (MalformedURLException e) {
					e.printStackTrace();
				}

				SharedPreferences prefs = PreferenceManager
						.getDefaultSharedPreferences(context);

				String cookie = prefs.getString("cookie", "");
				if (cookie.equals(""))
					new NotLoggedInException().printStackTrace();

				try {

					HttpURLConnection conn = (HttpURLConnection) myFileUrl
							.openConnection();
					conn.setDoInput(true);
					conn.addRequestProperty("Cookie", cookie);
					conn.connect();
					System.out.println("Length: " + conn.getContentLength());
					FlushedInputStream fis = new FlushedInputStream(conn
							.getInputStream());

					final Bitmap bmImg = BitmapFactory.decodeStream(fis);

					System.out.println("bmImg: " + bmImg);

					/* UI operations must be done on the UI thread */
					((Activity) context).runOnUiThread(new Runnable() {
						public void run() {
							b.view.setImageBitmap(bmImg);
						}
					});

				} catch (IOException e) {
					e.printStackTrace();
				}

			}

			/* Once queue is empty, pause thread. Thread should be
			 * interrupted when new images are queued for loading.
			 */
			synchronized (this) {
				while (imageQueue.isEmpty()) {
					try {
						wait();
					} catch (InterruptedException e) {
						// e.printStackTrace();
						break;
					}
				}	
			}

			/*
			 * try { loading = false; Thread.sleep(50); } catch
			 * (InterruptedException e) { System.out.println("Interrupted!");
			 * 
			 * loading = true; }
			 */
			
		}
	}


}
